package com.hjy.until;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.sun.corba.se.spi.ior.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

public class JsonUtils {

    private static Logger log = LoggerFactory.getLogger(JsonUtils.class);

    //默认不序列化值为null的字段
    private static final ObjectMapper deFaultObjectMapper = buildObjectMapper(JsonInclude.Include.NON_NULL);

    //序列化全部字段
    private static final ObjectMapper totalObjectMapper = buildObjectMapper(JsonInclude.Include.ALWAYS);

    private static ObjectMapper buildObjectMapper(JsonInclude.Include incl) {
        ObjectMapper mapper = new ObjectMapper();

        mapper.setSerializationInclusion(incl);

        // 没有映射到的属性不抛出异常
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        //处理时间格式
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        mapper.setDateFormat(dateFormat);

        mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
        // 允许注释
        mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        // 允许字段无引号
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        // 允许使用单引号
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

        SimpleModule module = new SimpleModule();
        module.addSerializer(ObjectId.class, new ObjectIdSerializer());
        mapper.registerModule(module);
        return mapper;
    }


    public static ObjectMapper getDeFaultObjectMapper() {
        return deFaultObjectMapper;
    }

    public static String toJson(Object bean) {
        try {
            return deFaultObjectMapper.writeValueAsString(bean);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    public static String toJsonWithNullFields(Object bean) {
        try {
            return totalObjectMapper.writeValueAsString(bean);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    public static <T> T toBean(String jsonString, Class<T> clazz) {
        try {
            return deFaultObjectMapper.readValue(jsonString, clazz);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public static <T> T toBean(String jsonString, TypeReference<T> typeReference) {
        try {
            return deFaultObjectMapper.readValue(jsonString, typeReference);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public static JsonNode toNode(String json) {
        try {
            return deFaultObjectMapper.readTree(json);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public static <T> T readFile(File file, Class<T> clazz) {
        try {
            return deFaultObjectMapper.readValue(new FileReader(file), clazz);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    static class ObjectIdSerializer extends JsonSerializer<ObjectId> {
        @Override
        public void serialize(ObjectId objectId, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (objectId == null) {
                jsonGenerator.writeString("");
            } else {
                jsonGenerator.writeString(objectId.toString());
            }
        }
    }

}